/**
 * 
 */
package inf.loansManagement;

import inf.exceptions.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import inf.main.Constraints;
import inf.mediasManagement.Media;
import inf.outils.StringCalendar;
import inf.specimensManagement.Specimen;
import inf.subscribersManagement.Subscriber;
import inf.loansManagement.Booking;

import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;


/**
 * @author  Fabre, Malric
 */


//column=@Column(name="id_specimen"))
@Entity
@Table(name="loans")
public class Loan implements java.io.Serializable  {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="id", unique = true, nullable = false)
	private long id;
	
	/**
	 * @uml.property  name="specimen"
	 * @uml.associationEnd  
	 */
	@OneToOne
	private Specimen specimen;
	
	/**
	 * @uml.property  name="specimen"
	 * @uml.associationEnd  
	 */
	@ManyToOne
	private Subscriber subscriber;
	
	/**
	 * @uml.property  name="dateReturn"
	 */
	
	private Calendar dateReturn;

	private Calendar startDate;

	/**
	 * @uml.property  name="returned"
	 */
	private Boolean returned;

	
	//Accessors
	
	/**
	 * @return
	 * @uml.property  name="returned"
	 */
	public Boolean getReturned() {
		return returned;
	}

	/**
	 * @param returned
	 * @uml.property  name="returned"
	 */
	public void setReturned(Boolean returned) {
		this.returned = returned;
	}

	/**
	 * Getter of the property <tt>specimen</tt>
	 * @return  Returns the specimen.
	 * @uml.property  name="specimen"
	 */
	public Specimen getSpecimen() {
		return specimen;
	}

	/**
	 * Setter of the property <tt>exemplary</tt>
	 * @param specimen  The exemplary to set.
	 * @uml.property  name="exemplary"
	 */
	public void setSpecimen(Specimen specimen) {
		this.specimen = specimen;
	}
	
	public Subscriber getSubscriber() {
		return subscriber;
	}

	public void setSubscriber(Subscriber subscriber) {
		this.subscriber = subscriber;
	}

	public Media getMedia() {
		return this.specimen.getMedia();
	}
	
	/**
	 * @return
	 * @uml.property  name="dateReturn"
	 */
	public Calendar getDateReturn() {
		return dateReturn;
	}

	/**
	 * @param dateReturn
	 * @uml.property  name="dateReturn"
	 */
	public void setDateReturn(Calendar dateReturn) {
		this.dateReturn = dateReturn;
	}
	
	public Calendar getStartDate() {
		return startDate;
	}

	public void setStartDate(Calendar date) {
		this.startDate = date;
	}
	
	//Constructors
	public Loan () {}

	public Loan(Specimen spec, Subscriber subscriber) throws BadParametersException {
		if ((spec == null) || (subscriber == null))
			throw new BadParametersException();
		
		this.setSpecimen(spec);
		
		Calendar returnDate = new GregorianCalendar();
		returnDate.add(Calendar.DATE, Constraints.loanDELAY);

		this.setStartDate(new GregorianCalendar());
		this.setDateReturn(returnDate);
		
		this.setSubscriber(subscriber);		
		this.setSpecimen(spec);
		this.setReturned(false);

		inf.loansManagement.LoanDAO.save(this);
	}
	
	public boolean equals(Object o) {
		Loan other = (Loan) o;
		if (this == other)
			return true;
		if (other == null || getClass() != other.getClass())
			return false;

		return true;
	}

	public int hashCode() {
		return (int) id;
	}

	@Override
	public String toString() {
		DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		return "Emprunt exemplaire = " + specimen.toString() + "\n" +
				"Par : " + this.getSubscriber().toString() + "\n" +
				"date d'emprunt = " + dateFormat.format(startDate.getTime()) + 
				", date de retour = " + dateFormat.format(dateReturn.getTime()) + "\n" +
				"emprunt termine = " + returned.toString();
	}

	public long getId() {
		return this.id;
	}


}
